# -*- coding: utf-8 -*-
'''
Created on Feb 24, 2010

@author: xen

Heavily inspired by http://github.com/Arachnid/bloggart/blob/master/static.py

'''
from google.appengine.api import memcache
from google.appengine.ext import db
from google.appengine.datastore import entity_pb

class MProxy:
  """ Прокси доступ к данным хранящимся в Big Table, позволяет чуть более простым образом
    запрашивать данные запрашиваемые по ключю.
  """
  def __init__(self, model, prefix=None, namespace=None, time=0):
    self.model = model
    self.prefix = prefix
    self.namespace = namespace
    self.time=time

  def get(self, key):
    """ У нас есть ключ и есть модель, теперь осталось проверить есть ли она в memchache.
      Если нет, то придется считывать из хранилища
    """
    entity = memcache.get(key, namespace=self.namespace)
    if entity:
      entity = db.model_from_protobuf(entity_pb.EntityProto(entity))
    else:
      entity = self.model.get_by_key_name(key)
      if entity:
        memcache.set(key, db.model_to_protobuf(entity).Encode(), time=self.time, namespace=self.namespace)
    
    return entity
 
  def gql(self, gql):
    """ Возможно метод который будет кешировать запросы """
    raise NotImplemented
   
  def set(self, key, **kwargs):
    """Сохраняет запись в модели при этом не забывая сохранить и в памяти
    """
    content = self.model(
        key_name=key,
        **kwargs)
    content.put()
    memcache.replace(key, db.model_to_protobuf(content).Encode(), time=self.time, namespace=self.namespace)
    return content
   
  def add(self, key, **kwargs):
    """ Добавляет запись и возвращает ее"""
    def _tx():
      if self.model.get_by_key_name(key):
        return None
      return set(key, **kwargs)
    return db.run_in_transaction(_tx)
   
  def remove(self, key):
    """ Удаляет запись и очищает память """
    memcache.delete(key, namespace=self.namespace)
    def _tx():
      content = self.model.get_by_key_name(key) 
      if not content:
        return
      content.delete() 
    return db.run_in_transaction(_tx)
   